In computer systems a variety of mechanisms and systems are implemented to protect against malware and software that has been modified without authorization. One of the most common methods is to provide a digital signature of the code or data which is checked before the code or data are executed or accessed. Methods for digitally signing code and data are widely used with software written for mobile devices, such as cellular telephones, due to the need to protect the security of cellular networks and the limited ability of mobile devices to implement malware protection software.
Code or data that is integrity protected by a digital signature is “signed” by a certifying authority or “signing server” before it is sold or otherwise distributed. Signed code or data includes a digital signature which contains an encrypted value that can be used in conjunction with a verification algorithm to verify that the code or data is the same as when it was “signed.” As illustrated in FIG. 1, in a typical implementation a computing device (e.g., a mobile device) confirms that an application is trustworthy by: unpacking the code or data to obtain the signature, step 2; running a hash function over the application code and/or data (or performing some other verification algorithm), step 4; decrypting the signature to obtain a hash value contained within the signature, step 6; confirming that the signature is signed by a valid certificate, step 8; and comparing the resulting hash to the hash contained within the digital signature, step 10. If the two hash values are equal, test 12, the code or data is trusted. Computers, such as mobile devices, may include a certificate chain in memory to enable them to decrypt the digital certificate and confirm that the signature is signed by a valid certificate. If the signature was signed by a valid certificate and the hash values are equal (i.e., test 12=“Yes”), the code or data are trusted and the client may execute the code or use the data.
Signing code and data provides an effective security shield in most cases. However, this security regime is static, and thus is unable to respond to changes in the security environment. For example, if a weakness is discovered in the implementation of any of the client core cryptographic components or if a fresh vulnerability against a core hash function or public key algorithm is discovered, or if a logic or application-level error is uncovered, the client device may not be able to protect itself from such vulnerabilities. To make matters worse, this situation may occur several years after the code and data were completed and distributed and years after the client device was commercially deployed.